package com.quanyan.ic.datacenter.dao.impl;

import com.github.ltsopensource.core.commons.utils.DateUtils;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.quanyan.ic.common.utils.CalendarDateUtils;
import com.quanyan.ic.datacenter.constant.Constants;
import com.quanyan.ic.datacenter.dao.AlarmDayReportOfPlaceDao;
import com.quanyan.ic.datacenter.http.req.ReqReport;
import com.quanyan.ic.datacenter.http.resp.RespAlarmsTimePointLineChart;
import com.quanyan.ic.datacenter.mapper.icData.AlarmDayReportOfPlaceMapper;
import com.quanyan.ic.datacenter.mapper.icData.entity.AlarmDayReportOfPlace;
import com.quanyan.ic.datacenter.mapper.icData.entity.AlarmDayReportOfPlaceExample;
import com.quanyan.ic.datacenter.model.AlarmDayReportParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.*;

/**
 * Created by Administrator on 2017/8/26.
 */
@Repository
class AlarmDayReportOfPlaceDaoImpl implements AlarmDayReportOfPlaceDao {

    @Autowired
    private AlarmDayReportOfPlaceMapper alarmDayReportOfPlaceMapper;

    @Override
    public List<RespAlarmsTimePointLineChart> findAlarmDayReportPlace(ReqReport reqReport) {
        List<Date> dateList  = CalendarDateUtils.findDates(reqReport.getStartDate(),reqReport.getEndDate());
        AlarmDayReportOfPlaceExample example = new AlarmDayReportOfPlaceExample();
        AlarmDayReportOfPlaceExample.Criteria criteria = example.createCriteria();
        criteria.andDateGreaterThanOrEqualTo(reqReport.getStartDate());
        criteria.andDateLessThan(reqReport.getEndDate());
        List<AlarmDayReportOfPlace> dbList =  alarmDayReportOfPlaceMapper.selectByExample(example);
        List<RespAlarmsTimePointLineChart> result = new ArrayList<>();
        if ( dbList != null && dbList.size() > 0 ){
            List<Integer> listPlace = new ArrayList<>();
            listPlace.addAll(ImmutableSet.copyOf(this.covertToPlaceId(dbList)).asList());
            for (Integer placeId : listPlace ){
                RespAlarmsTimePointLineChart lineChart = new RespAlarmsTimePointLineChart();
                lineChart.setId(placeId);
                Map<String,Integer> tempMap = this.getDateMap(dateList);
                lineChart.setOrderMap(tempMap);
                lineChart.setVideoMap(tempMap);
                lineChart.setLightMap(tempMap);
                for ( AlarmDayReportOfPlace db : dbList ){
                    if (  placeId == db.getPlaceId().intValue() ){
                        lineChart.setName(db.getPlaceName());
//                        lineChart.getOrderLineChart().add(db.getOrderCount());
//                        lineChart.getLightLineChart().add(db.getLightAlarmsMinutes());
//                        lineChart.getVideoLineChart().add(db.getVideoAlarmsMinutes());
                        String dateYmd = DateUtils.formatYMD(db.getDate());
                        lineChart.getOrderMap().put(dateYmd,db.getOrderCount());
                        lineChart.getLightMap().put(dateYmd,db.getLightAlarmsMinutes());
                        lineChart.getVideoMap().put(dateYmd,db.getVideoAlarmsMinutes());
                    }
                }
                result.add(lineChart);
            }
        }
        return result;
    }


    public void consumerOrder(AlarmDayReportParam param){
        Integer placeId = param.getPlaceId();
        Integer cityId = param.getCityId();
        Date date = param.getDate() ;
        byte type = param.getType();
        Integer min = param.getMin();
        AlarmDayReportOfPlaceExample example = new AlarmDayReportOfPlaceExample();
        AlarmDayReportOfPlaceExample.Criteria criteria = example.createCriteria();
        criteria.andPlaceIdEqualTo(placeId);
        criteria.andDateEqualTo(date);
        List<AlarmDayReportOfPlace> list = alarmDayReportOfPlaceMapper.selectByExample(example);
        if ( list != null && list.size() > 0){
            AlarmDayReportOfPlace place = list.get(0);
            AlarmDayReportOfPlace update = new AlarmDayReportOfPlace();
            update.setId(place.getId());
            if (Constants.AlarmsType.order == type){
                update.setOrderCount(place.getOrderCount() + 1 );
                update.setOrderMinutes(place.getOrderMinutes() + min );
            }
            else if (Constants.AlarmsType.alarms_type_video == type){
                update.setVideoAlarmsCount(place.getVideoAlarmsCount() + 1);
                update.setVideoAlarmsCount(place.getVideoAlarmsMinutes() + min);
            }else if (Constants.AlarmsType.alarms_type_light == type){
                update.setLightAlarmsCount(place.getLightAlarmsCount() + 1);
                update.setLightAlarmsMinutes(place.getLightAlarmsMinutes() + min);
                if (param.getHandLight() != null){
                    update.setHandLightCount(place.getLightAlarmsCount() + 1);
                    update.setHandLightMinutes(place.getLightAlarmsMinutes() + min);
                }
            }
            alarmDayReportOfPlaceMapper.updateByPrimaryKeySelective(update);
        }else {
            AlarmDayReportOfPlace insert = new AlarmDayReportOfPlace();
            insert.setCityId(cityId);
            insert.setCityName(param.getCityName());
            insert.setPlaceId(placeId);
            insert.setPlaceName(param.getPlaceName());
            insert.setDate(date);
            if (Constants.AlarmsType.order == type){
                insert.setOrderCount( 1 );
                insert.setOrderMinutes( min );
            }
            else if (Constants.AlarmsType.alarms_type_video == type){
                insert.setVideoAlarmsCount(1);
                insert.setVideoAlarmsCount( min);
            }else if (Constants.AlarmsType.alarms_type_light == type){
                insert.setLightAlarmsCount(1);
                insert.setLightAlarmsMinutes( min);
                if (param.getHandLight() != null){
                    insert.setHandLightCount( 1);
                    insert.setHandLightMinutes( min);
                }
            }
            alarmDayReportOfPlaceMapper.insertSelective(insert);
        }
    }
    
    

    //list 按属性生成一个新的 list
    public  ImmutableMultiset<Integer> covertToPlaceId(List<AlarmDayReportOfPlace> dbList) {
        return ImmutableMultiset.copyOf(Lists.transform(dbList, new Function<AlarmDayReportOfPlace, Integer>() {
                    @Override
                    public Integer apply(AlarmDayReportOfPlace input) {
                        return input.getPlaceId();
                    }
                }
        ));
    }

    public Map<String ,Integer> getDateMap(List<Date> dateList ){
        Map<String ,Integer> map = new HashMap<>();
        if ( dateList != null && dateList.size() > 0){
            for (Date d :dateList){
                map.put(DateUtils.formatYMD(d),0);
            }
        }
        return this.sortMapByKey(map);
    }

    /**
     * 使用 Map按key进行排序
     * @param map
     * @return
     */
    public  Map<String, Integer> sortMapByKey(Map<String, Integer> map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, Integer> sortMap = new TreeMap<String, Integer>(new MapKeyComparator());
        sortMap.putAll(map);
        return sortMap;
    }

    public class MapKeyComparator implements Comparator<String>{
        public int compare(String str1, String str2) {
            return str1.compareTo(str2);
        }
    }
}
